from mcp.server.fastmcp import FastMCP

# 创建MCP服务实例
mcp = FastMCP("Elliptic Curve Operations Service")

@mcp.tool()
def point_addition(p: tuple, q: tuple, a: int, p_mod: int) -> tuple:
    """椭圆曲线点加法运算
    
    Args:
        p: 第一个点 (x1, y1)
        q: 第二个点 (x2, y2)
        a: 椭圆曲线参数a
        p_mod: 模数
        
    Returns:
        点加法结果 (x3, y3)
    """
    try:
        x1, y1 = p
        x2, y2 = q
        
        # 处理无穷远点情况
        if x1 is None and y1 is None:
            return q
        if x2 is None and y2 is None:
            return p
        
        # 处理点互为逆元情况
        if x1 == x2 and (y1 + y2) % p_mod == 0:
            return (None, None)
        
        # 计算斜率
        if p == q:
            # 点加倍情况
            numerator = (3 * x1 * x1 + a) % p_mod
            denominator = (2 * y1) % p_mod
        else:
            # 不同点相加
            numerator = (y2 - y1) % p_mod
            denominator = (x2 - x1) % p_mod
        
        # 计算分母的模逆
        inv_denominator = pow(denominator, -1, p_mod)
        s = (numerator * inv_denominator) % p_mod
        
        # 计算新点坐标
        x3 = (s * s - x1 - x2) % p_mod
        y3 = (s * (x1 - x3) - y1) % p_mod
        
        return (x3, y3)
    except Exception as e:
        raise ValueError(f"点加法运算失败: {str(e)}")

@mcp.tool()
def point_multiplication(k: int, p: tuple, a: int, p_mod: int) -> tuple:
    """椭圆曲线点乘法运算
    
    Args:
        k: 乘数
        p: 基点 (x, y)
        a: 椭圆曲线参数a
        p_mod: 模数
        
    Returns:
        点乘法结果 (x, y)
    """
    try:
        if k == 0:
            return (None, None)
            
        result = (None, None)
        current = p
        
        while k > 0:
            if k % 2 == 1:
                result = point_addition(result, current, a, p_mod)
            current = point_addition(current, current, a, p_mod)
            k = k // 2
            
        return result
    except Exception as e:
        raise ValueError(f"点乘法运算失败: {str(e)}")

if __name__ == "__main__":
    print("Elliptic Curve Operations Service 启动...")
    mcp.run(transport="stdio")